#include "ti_msp_dl_config.h"

#include "ti/driverlib/dl_gpio.h"
#include "stdio.h"

#define SDA_GET()   ( ( ( DL_GPIO_readPins(GPIOB,I2C_SDA_PIN) & I2C_SDA_PIN ) > 0 ) ? 1 : 0 )

/*引脚配置层*/
void I2C_W_SCL(uint8_t x)
{
	if (x)
	{
		DL_GPIO_setPins(GPIOB,I2C_SCL_PIN);
	}
	else
	{
		DL_GPIO_clearPins(GPIOB,I2C_SCL_PIN);
	
	}
	delay_cycles(2);
}
void I2C_W_SDA(uint8_t x)
{
	// SDA_OUT();
	if (x)
	{
		DL_GPIO_setPins(GPIOB,I2C_SDA_PIN);
	}
	else
	{
		DL_GPIO_clearPins(GPIOB,I2C_SDA_PIN);
	}
	delay_cycles(2);
}


/*引脚初始化*/
void MyI2C_Init(void)
{
	SYSCFG_DL_init();
	
	I2C_W_SCL(1);
	I2C_W_SDA(1);
}

/*协议层*/

/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void MyI2C_Start(void)
{
	// SDA_OUT();
	I2C_W_SDA(1);
	I2C_W_SCL(1);
	I2C_W_SDA(0);
	I2C_W_SCL(0);
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void MyI2C_Stop(void)
{
	// SDA_OUT();
	I2C_W_SDA(0);
	I2C_W_SCL(1);
	I2C_W_SDA(1);
}

void MyI2C_SendByte(uint8_t Byte)
{
	uint8_t i;
	for (i = 0; i < 8; i ++)				//循环8次，主机依次发送数据的每一位
	{
		/*两个!可以对数据进行两次逻辑取反，作用是把非0值统一转换为1，即：!!(0) = 0，!!(非0) = 1*/
		I2C_W_SDA(!!(Byte & (0x80 >> i)));//使用掩码的方式取出Byte的指定一位数据并写入到SDA线
		I2C_W_SCL(1);						//释放SCL，从机在SCL高电平期间读取SDA
		I2C_W_SCL(0);						//拉低SCL，主机开始发送下一位数据
	}
}

uint8_t MyI2C_ReceiveByte(void)
{
	unsigned char i,receive=0;
    // SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
    {
        I2C_W_SCL(0);
        delay_cycles(32);
        I2C_W_SCL(1);
        delay_cycles(32);
        receive<<=1;
        if( SDA_GET() )
        {
            receive|=1;
        }
        delay_cycles(32);
    }
	 I2C_W_SCL(0);

    return receive;
}

void MyI2C_SendAck(uint8_t AckBit)
{
	I2C_W_SDA(AckBit);					//主机把应答位数据放到SDA线
	I2C_W_SCL(1);							//释放SCL，从机在SCL高电平期间，读取应答位
	I2C_W_SCL(0);							//拉低SCL，开始下一个时序模块
}

uint8_t MyI2C_ReceiveAck(void)
{
	uint8_t AckBit;							//定义应答位变量
	I2C_W_SDA(1);							//接收前，主机先确保释放SDA，避免干扰从机的数据发送
	I2C_W_SCL(1);							//释放SCL，主机机在SCL高电平期间读取SDA
	AckBit = SDA_GET();					//将应答位存储到变量里
	I2C_W_SCL(0);							//拉低SCL，开始下一个时序模块
	return AckBit;							//返回定义应答位变量
}
